#!/usr/bin/env python3
import numpy as np

samples_and = [
    [0, 0, 0],
    [1, 0, 0],
    [0, 1, 0],
    [1, 1, 1],
]#逻辑与数据，前两列是data,最后一列是label


samples_or = [
    [0, 0, 0],
    [1, 0, 1],
    [0, 1, 1],
    [1, 1, 1],
]


samples_xor = [
    [0, 0, 0],
    [1, 0, 1],
    [0, 1, 1],
    [1, 1, 0],
] #逻辑异或数据


#定义了一个感知器
def perceptron(samples):
    w = np.array([1, 2]) #一行两列的权重参数，初始化参数，1,2
    b = 0 #截距项（神经网络带有一些固有的属性）
    a = 1 #学习率

    for i in range(10): #感知器要更新多少次，10个epoch
        for j in range(4): #四条数据
            #感知器的构建
            x = np.array(samples[j][:2]) #获取第J行的前两列（python的切片语法）
            #if np.dot(w,x) + b > 0: #激活函数，阶跃函数大于0， y输出为1
                  # y = 1
                   #else:
                         # y = 0
            y = 1 if np.dot(w, x) + b > 0 else 0
            
            d = np.array(samples[j][2]) #获取第j行，第二列
            #反向传播公式推导而得
            delta_b = a*(d-y) #训练结果和实际结果的梯度，（d - y）是一个误差，损失往前传播
            delta_w = a*(d-y)*x#权重系数的梯度，（d - y）* x, x表示输入

            print('epoch {} sample {}  [{} {} {} {} {} {} {}]'.format(
                i, j, w[0], w[1], b, y, delta_w[0], delta_w[1], delta_b
            )) #python中format用法
            w = w + delta_w #权重系数修正
            b = b + delta_b #截距系数修正


if __name__ == '__main__': #每一个py文件都有一个name,类似于C语言中的main函数
    print('logical and')
    perceptron(samples_and) #每一次只是输入一个矩阵进行训练，逻辑与矩阵在第二轮已经完成训练，梯度值不再发生变化，最终对应的系数为w[0], w[1], b,1,2-2
    print('logical or')
    perceptron(samples_or)
    print('logical xor')
    perceptron(samples_xor)
